package com.example.sbbsec;

import lombok.Builder;
import lombok.Data;
import org.springframework.cache.Cache;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.DoubleSupplier;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.stream.Stream;

import static com.google.common.collect.Lists.charactersOf;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Maps.newIdentityHashMap;

/**
 * Created by Arat.Wu on 2018/12/04.
 */
public class FuctionalMethods {

    public static <T,R> List<R> multiGetResult(List<Function<List<T>, R>> functions, List<T> list) {
        return functions.stream().map(f -> f.apply(list)).collect(Collectors.toList());
    }

    public static <T,R> List<R> multiGetResult(Consumer<List<T>> consumer,List<Function<List<T>, R>> functions, List<T> list) {
        consumer.accept(list);
        return functions.stream().map(f -> f.apply(list)).collect(Collectors.toList());
    }
    
    public static <T,R> List<R> multiGetResult(List<Function<Supplier<List<T>>, R>> functions, Supplier<List<T>> list) {
        return functions.stream().map(f -> f.apply(list)).collect(Collectors.toList());
    }

    public static <T> Supplier<List<T>> getSupplier(List<T> list) {
        return () -> new ArrayList<>(list);
    }
    public static int compareDesc(int x, int y){
        return Integer.compare(y, x);
    }



    public static void main(String[] args) {
//        System.out.println(multiGetResult(
//                Arrays.asList(
//
//                        list -> list.get().stream().sorted().map(Math::sqrt).collect(Collectors.toMap(x->x, y->Math.pow(2,y)))),
//                getSupplier(Arrays.asList(64, 49, 25, 16, 9, 4, 1, 81, 36))));
//

        List<Integer> list = Arrays.asList(64, 49, 25, 16, 9, 4, 1, 81, 36);
        List<Integer> list2 = Arrays.asList(64, 49, 25, 16, 9, 4, 1, 81, 36);

/*        Supplier<Map<Integer, Integer>> mapSupplier = () -> list.stream().collect(Collectors.toMap(x -> x, y -> y,(v1,v2)-> v1+v2,()->list.stream().collect(Collectors.toMap(x->x, y-> y))));

        Supplier<Map<Integer,Integer>> mapSupplier2 = () -> list.stream().collect(Collectors.toMap(x->x, y-> y));


        System.out.println(mapSupplier2);
        Map<Integer, Integer> mapValueAdd = list.stream().collect(Collectors.toMap(x -> x, y -> y, (v1, v2) -> v1 + v2, mapSupplier2));
        System.out.println(mapValueAdd);*/

        List<Integer> list3 = Arrays.asList(64, 49, 25, 16, 9, 4, 1, 81, 36,36);
        List<Integer> list5 = Arrays.asList(64, 49, 25, 16, 9, 4, 0, 81, 99);
        List<List<Integer>> list4 = newArrayList();
        list4.add(list3);
        list4.add(list5);
        List<Map<Integer,Integer>> list6 = newArrayList();
        list6.add(list3.stream().collect(Collectors.toMap(x->x,y->y,(v1,v2)->0)));

        list6.add(list5.stream().collect(Collectors.toMap(x->x,y->y,(v1,v2)->v2)));

/*        System.out.println(list4.stream().max(Comparator.comparingInt(x -> x.stream().sorted((a, b) -> Integer.compare(b, a)).collect(Collectors.toList()).get(0))));
        List<List<Long>> collect = list4.stream().map(x -> x.stream().map(Long::valueOf).collect(Collectors.toList())).collect(Collectors.toList());
        List<Long> collect1 = list4.stream().flatMap(x -> x.stream().map(Long::valueOf)).collect(Collectors.toList());
        final List<Map.Entry<Integer, Integer>> collect2 = list6.stream().flatMap(x -> x.entrySet().stream()).collect(Collectors.toList());
        System.out.println(list6.stream().count());
        list6.stream().flatMap(x->x.entrySet().stream()).sorted((a, b) -> Integer.compare(b.getValue(), a.getValue())).forEachOrdered(System.out::println);

        list6.parallelStream().flatMap(x->x.entrySet().stream())
                .sorted(Comparator.comparingInt(Map.Entry::getValue)).forEachOrdered(System.out::println);

        final Map<Integer, List<Map.Entry<Integer, Integer>>> collect3 = list6.stream().flatMap(x -> x.entrySet().stream()).collect(Collectors.groupingBy(Map.Entry::getKey));
        */
        list6.stream().map(x->x.entrySet().stream().peek(System.out::println).collect(Collectors.groupingBy(Map.Entry::getKey))).collect(Collectors.toList());

        List<String> streamMap = Stream.of("a", "b", "c").map(String::toUpperCase).collect(Collectors.toList());
        Stream.of(list).peek(System.out::println).count();
        Integer reduce = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);
        System.out.println(reduce);
        int i=1;

    }


}
